lib/sign: initial implementation
authorDenis Pynkin <denis.pynkin@collabora.com>
Sun, 28 Jul 2019 23:32:28 +0000 (02:32 +0300)
committerDenis Pynkin <denis.pynkin@collabora.com>
Wed, 25 Mar 2020 12:23:54 +0000 (15:23 +0300)
Added the initial version of signing interface allowing to allowing to
sign and verify commits.
Implemented initial signing modules:
 - dummy -- simple module allowing to sign/verify with ASCII string
 - ed25519 -- module allowing to sign/verify commit with ed25519
   (EdDSA) signature scheme provided by libsodium library.

Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
Makefile-libostree-defines.am
Makefile-libostree.am
Makefile-ostree.am
apidoc/ostree-sections.txt
src/libostree/libostree-devel.sym
src/libostree/ostree-sign-dummy.c [new file with mode: 0644]
src/libostree/ostree-sign-dummy.h [new file with mode: 0644]
src/libostree/ostree-sign-ed25519.c [new file with mode: 0644]
src/libostree/ostree-sign-ed25519.h [new file with mode: 0644]
src/libostree/ostree-sign.c [new file with mode: 0644]
src/libostree/ostree-sign.h [new file with mode: 0644]

index 060351571239541be8de4d2d27d1e7461226d6d6..43e0928150b3286140eb175cff93f29f69bd1ef0 100644 (file)
@@ -46,6 +46,8 @@ libostree_public_headers = \
        src/libostree/ostree-repo-finder-mount.h \
        src/libostree/ostree-repo-finder-override.h \
        src/libostree/ostree-kernel-args.h \
+       src/libostree/ostree-sign.h \
+       src/libostree/ostree-sign-ed25519.h \
        $(NULL)
 
 # This one is generated via configure.ac, and the gtk-doc
index a7e7e1239d46230e95ee5faacc725679188d0f29..c0a7ac9f2e5839dbd397c4ccf1f1718e61ad9844 100644 (file)
@@ -262,6 +262,20 @@ libostree_1_la_CFLAGS += $(OT_DEP_SELINUX_CFLAGS)
 libostree_1_la_LIBADD += $(OT_DEP_SELINUX_LIBS)
 endif
 
+libostree_1_la_SOURCES += \
+       src/libostree/ostree-sign.c \
+       src/libostree/ostree-sign.h \
+       src/libostree/ostree-sign-dummy.c \
+       src/libostree/ostree-sign-dummy.h \
+       src/libostree/ostree-sign-ed25519.c \
+       src/libostree/ostree-sign-ed25519.h \
+       $(NULL)
+
+if USE_LIBSODIUM
+libostree_1_la_CFLAGS += $(OT_DEP_LIBSODIUM_CFLAGS)
+libostree_1_la_LIBADD += $(OT_DEP_LIBSODIUM_LIBS)
+endif # USE_LIBSODIUM
+
 # XXX: work around clang being passed -fstack-clash-protection which it doesn't understand
 # See: https://bugzilla.redhat.com/show_bug.cgi?id=1672012
 INTROSPECTION_SCANNER_ENV = CC=gcc
index 470d23d36fe5df82ca6262daf2169f06a545f96c..f37d974af597699414ceeb198aecafa337ceffb6 100644 (file)
@@ -112,11 +112,6 @@ ostree_SOURCES += \
        $(NULL)
 endif
 
-if USE_LIBSODIUM
-ostree_CFLAGS += $(OT_DEP_LIBSODIUM_CFLAGS)
-ostree_LDADD += $(OT_DEP_LIBSODIUM_LIBS)
-endif # USE_LIBSODIUM
-
 if USE_CURL_OR_SOUP
 ostree_SOURCES += src/ostree/ot-remote-builtin-add-cookie.c \
   src/ostree/ot-remote-builtin-delete-cookie.c \
@@ -166,3 +161,8 @@ if USE_LIBARCHIVE
 ostree_CFLAGS += $(OT_DEP_LIBARCHIVE_CFLAGS)
 ostree_LDADD += $(OT_DEP_LIBARCHIVE_LIBS)
 endif
+
+if USE_LIBSODIUM
+ostree_CFLAGS += $(OT_DEP_LIBSODIUM_CFLAGS)
+ostree_LDADD += $(OT_DEP_LIBSODIUM_LIBS)
+endif # USE_LIBSODIUM
index 3525d9f28832af620d48fe87076174e49287d2ca..cfc4a3406b19fd3f121bb478c2cacde8f2ea8c25 100644 (file)
@@ -705,3 +705,26 @@ ostree_kernel_args_from_string
 ostree_kernel_args_to_strv
 ostree_kernel_args_to_string
 </SECTION>
+
+<SECTION>
+<FILE>ostree-sign</FILE>
+OstreeSign
+OstreeSignDummy
+OstreeSignEd25519
+ostree_sign_list_names
+ostree_sign_commit
+ostree_sign_commit_verify
+ostree_sign_data
+ostree_sign_get_by_name
+ostree_sign_get_name
+ostree_sign_detached_metadata_append
+ostree_sign_metadata_verify
+ostree_sign_load_pk
+ostree_sign_set_pk
+ostree_sign_set_sk
+ostree_sign_ed25519_keypair_generate
+<SUBSECTION Standard>
+ostree_sign_get_type
+ostree_sign_dummy_get_type
+ostree_sign_ed25519_get_type
+</SECTION>
index 3d5fd3bcdf1d5f7d19a0aa95b3c0965367955db1..4066f383910b25ed7275e363463d39b2c8d2a66b 100644 (file)
 LIBOSTREE_2020.2 {
 global:
   ostree_repo_commit_modifier_set_sepolicy_from_commit;
+  someostree_symbol_deleteme;
+  ostree_sign_get_type;
+  ostree_sign_list_names;
+  ostree_sign_commit;
+  ostree_sign_commit_verify;
+  ostree_sign_data;
+  ostree_sign_get_by_name;
+  ostree_sign_get_name;
+  ostree_sign_detached_metadata_append;
+  ostree_sign_metadata_verify;
+  ostree_sign_load_pk;
+  ostree_sign_set_pk;
+  ostree_sign_set_sk;
+  ostree_sign_dummy_get_type;
+  ostree_sign_ed25519_get_type;
+  ostree_sign_ed25519_keypair_generate;
 } LIBOSTREE_2020.1;
 
 /* Stub section for the stable release *after* this development one; don't
diff --git a/src/libostree/ostree-sign-dummy.c b/src/libostree/ostree-sign-dummy.c
new file mode 100644 (file)
index 0000000..e489a98
--- /dev/null
@@ -0,0 +1,181 @@
+/* vim:set et sw=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e2s: */
+
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "ostree-sign-dummy.h"
+#include <string.h>
+
+#define OSTREE_SIGN_DUMMY_NAME "dummy"
+
+#define OSTREE_SIGN_METADATA_DUMMY_KEY "ostree.sign.dummy"
+#define OSTREE_SIGN_METADATA_DUMMY_TYPE "aay"
+
+#define OSTREE_SIGN_DUMMY_SIGNATURE "dummysign"
+
+struct _OstreeSignDummy
+{
+  GObject parent;
+  gchar *signature_ascii;
+};
+
+static void
+ostree_sign_dummy_iface_init (OstreeSignInterface *self);
+
+G_DEFINE_TYPE_WITH_CODE (OstreeSignDummy, ostree_sign_dummy, G_TYPE_OBJECT,
+        G_IMPLEMENT_INTERFACE (OSTREE_TYPE_SIGN, ostree_sign_dummy_iface_init));
+
+static void
+ostree_sign_dummy_iface_init (OstreeSignInterface *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  self->data = ostree_sign_dummy_data;
+  self->get_name = ostree_sign_dummy_get_name;
+  self->metadata_key = ostree_sign_dummy_metadata_key;
+  self->metadata_format = ostree_sign_dummy_metadata_format;
+  self->metadata_verify = ostree_sign_dummy_metadata_verify;
+  self->set_sk = ostree_sign_dummy_set_signature;
+  self->set_pk = ostree_sign_dummy_set_signature;
+}
+
+static void
+ostree_sign_dummy_class_init (OstreeSignDummyClass *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  GObjectClass *object_class = G_OBJECT_CLASS(self);
+}
+
+static void
+ostree_sign_dummy_init (OstreeSignDummy *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  self->signature_ascii = g_strdup(OSTREE_SIGN_DUMMY_SIGNATURE);
+}
+
+gboolean ostree_sign_dummy_set_signature (OstreeSign *self, GVariant *key, GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  OstreeSignDummy *sign =  ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self));
+
+  if (sign->signature_ascii != NULL)
+    g_free(sign->signature_ascii);
+
+  sign->signature_ascii = g_variant_dup_string (key, 0);
+
+  return TRUE;
+}
+
+gboolean ostree_sign_dummy_data (OstreeSign *self,
+                                 GBytes *data,
+                                 GBytes **signature,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+  OstreeSignDummy *sign =  ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self));
+
+  *signature = g_bytes_new (sign->signature_ascii, strlen(sign->signature_ascii));
+
+  return TRUE;
+}
+
+gchar * ostree_sign_dummy_get_name (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+  g_autofree gchar *name = g_strdup(OSTREE_SIGN_DUMMY_NAME);
+
+  return g_steal_pointer (&name);
+}
+
+gchar * ostree_sign_dummy_metadata_key (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_autofree gchar *key = g_strdup(OSTREE_SIGN_METADATA_DUMMY_KEY);
+  return g_steal_pointer (&key);
+}
+
+gchar * ostree_sign_dummy_metadata_format (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_autofree gchar *type = g_strdup(OSTREE_SIGN_METADATA_DUMMY_TYPE);
+  return g_steal_pointer (&type);
+}
+
+gboolean ostree_sign_dummy_metadata_verify (OstreeSign *self,
+                                            GBytes     *data,
+                                            GVariant   *signatures,
+                                            GError     **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+  g_return_val_if_fail (data != NULL, FALSE);
+
+  OstreeSignDummy *sign =  ostree_sign_dummy_get_instance_private(OSTREE_SIGN_DUMMY(self));
+
+  gboolean ret = FALSE;
+
+  if (signatures == NULL)
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "signature: dummy: commit have no signatures of my type");
+      goto err;
+    }
+
+
+  if (!g_variant_is_of_type (signatures, (GVariantType *) OSTREE_SIGN_METADATA_DUMMY_TYPE))
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "signature: dummy: wrong type passed for verification");
+      goto err;
+    }
+
+  for (gsize i = 0; i < g_variant_n_children(signatures); i++)
+    {
+      g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i);
+      g_autoptr (GBytes) signature = g_variant_get_data_as_bytes(child);
+
+      gsize sign_size = 0;
+      g_bytes_get_data (signature, &sign_size);
+      g_autofree gchar *sign_ascii = g_strndup(g_bytes_get_data (signature, NULL), sign_size);
+      g_debug("Read signature %d: %s", (gint)i, sign_ascii);
+
+      if (!g_strcmp0(sign_ascii, sign->signature_ascii))
+          ret = TRUE;
+    }
+
+err:
+  return ret;
+}
diff --git a/src/libostree/ostree-sign-dummy.h b/src/libostree/ostree-sign-dummy.h
new file mode 100644 (file)
index 0000000..8bbd407
--- /dev/null
@@ -0,0 +1,63 @@
+/* vim:set et sw=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e2s: */
+
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *  - Denis Pynkin (d4s) <denis.pynkin@collabora.com>
+ */
+
+#pragma once
+
+#include "ostree-sign.h"
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_SIGN_DUMMY (ostree_sign_dummy_get_type ())
+
+_OSTREE_PUBLIC
+G_DECLARE_FINAL_TYPE (OstreeSignDummy,
+                      ostree_sign_dummy,
+                      OSTREE,
+                      SIGN_DUMMY,
+                      GObject)
+
+gchar * ostree_sign_dummy_get_name (OstreeSign *self);
+
+gboolean ostree_sign_dummy_data (OstreeSign *self,
+                                 GBytes *data,
+                                 GBytes **signature,
+                                 GCancellable *cancellable,
+                                 GError **error);
+
+gchar * ostree_sign_dummy_metadata_key (OstreeSign *self);
+gchar * ostree_sign_dummy_metadata_format (OstreeSign *self);
+
+gboolean ostree_sign_dummy_metadata_verify (OstreeSign *self,
+                                            GBytes     *data,
+                                            GVariant   *signatures,
+                                            GError     **error);
+
+gboolean ostree_sign_dummy_set_signature (OstreeSign *self, GVariant *key, GError **error);
+
+void ostree_sign_dummy_finalize (GObject *gobject);
+
+G_END_DECLS
+
diff --git a/src/libostree/ostree-sign-ed25519.c b/src/libostree/ostree-sign-ed25519.c
new file mode 100644 (file)
index 0000000..e3ab6b5
--- /dev/null
@@ -0,0 +1,342 @@
+/* vim:set et sw=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e2s: */
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *  - Denis Pynkin (d4s) <denis.pynkin@collabora.com>
+ */
+
+#include "config.h"
+
+#include "ostree-sign-ed25519.h"
+#ifdef HAVE_LIBSODIUM
+#include <sodium.h>
+#endif
+
+#define OSTREE_SIGN_ED25519_NAME "ed25519"
+
+#define OSTREE_SIGN_METADATA_ED25519_KEY "ostree.sign.ed25519"
+#define OSTREE_SIGN_METADATA_ED25519_TYPE "aay"
+
+struct _OstreeSignEd25519
+{
+  GObject parent;
+  gboolean initialized;
+  guchar *secret_key;
+  guchar *public_key;
+};
+
+static void
+ostree_sign_ed25519_iface_init (OstreeSignInterface *self);
+
+G_DEFINE_TYPE_WITH_CODE (OstreeSignEd25519, ostree_sign_ed25519, G_TYPE_OBJECT,
+        G_IMPLEMENT_INTERFACE (OSTREE_TYPE_SIGN, ostree_sign_ed25519_iface_init));
+
+static void
+ostree_sign_ed25519_iface_init (OstreeSignInterface *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  self->data = ostree_sign_ed25519_data;
+  self->get_name = ostree_sign_ed25519_get_name;
+  self->metadata_key = ostree_sign_ed25519_metadata_key;
+  self->metadata_format = ostree_sign_ed25519_metadata_format;
+  self->metadata_verify = ostree_sign_ed25519_metadata_verify;
+  self->set_sk = ostree_sign_ed25519_set_sk;
+  self->set_pk = ostree_sign_ed25519_set_pk;
+}
+
+static void
+ostree_sign_ed25519_class_init (OstreeSignEd25519Class *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  GObjectClass *object_class = G_OBJECT_CLASS(self);
+}
+
+static void
+ostree_sign_ed25519_init (OstreeSignEd25519 *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  self->initialized = TRUE;
+  self->secret_key = NULL;
+  self->public_key = NULL;
+
+#ifdef HAVE_LIBSODIUM
+  if (sodium_init() < 0)
+    {
+      self->initialized = FALSE;
+      g_warning ("libsodium library couldn't be initialized");
+    }
+#else
+  g_error ("ed25519 signature isn't supported");
+#endif /* HAVE_LIBSODIUM */
+}
+
+gboolean ostree_sign_ed25519_data (OstreeSign *self,
+                                   GBytes *data,
+                                   GBytes **signature,
+                                   GCancellable *cancellable,
+                                   GError **error)
+{
+
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+  OstreeSignEd25519 *sign = ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self));
+
+#ifdef HAVE_LIBSODIUM
+  g_autofree guchar *sig = NULL;
+#endif
+
+  if ((sign->initialized != TRUE) || (sign->secret_key == NULL))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                          "Not able to sign: libsodium library isn't initialized properly");
+      goto err;
+    }
+#ifdef HAVE_LIBSODIUM
+  unsigned long long sig_size = 0;
+
+  sig = g_malloc0(crypto_sign_BYTES);
+
+  if (crypto_sign_detached (sig,
+                            &sig_size,
+                            g_bytes_get_data (data, NULL),
+                            g_bytes_get_size (data),
+                            sign->secret_key))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                          "Not able to sign the object");
+      goto err;
+    }
+
+  g_debug ("sign: data hash = 0x%x", g_bytes_hash(data));
+  *signature = g_bytes_new (sig, sig_size);
+  return TRUE;
+#endif /* HAVE_LIBSODIUM */
+err:
+  return FALSE;
+}
+
+gchar * ostree_sign_ed25519_get_name (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+  g_autofree gchar *name = g_strdup (OSTREE_SIGN_ED25519_NAME);
+
+  return g_steal_pointer (&name);
+}
+
+gchar * ostree_sign_ed25519_metadata_key (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_autofree gchar *key = g_strdup(OSTREE_SIGN_METADATA_ED25519_KEY);
+  return g_steal_pointer (&key);
+}
+
+gchar * ostree_sign_ed25519_metadata_format (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_autofree gchar *type = g_strdup (OSTREE_SIGN_METADATA_ED25519_TYPE);
+  return g_steal_pointer (&type);
+}
+
+gboolean ostree_sign_ed25519_metadata_verify (OstreeSign *self,
+                                            GBytes     *data,
+                                            GVariant   *signatures,
+                                            GError     **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+  g_return_val_if_fail (data != NULL, FALSE);
+  gboolean ret = FALSE;
+
+  OstreeSignEd25519 *sign = ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self));
+
+  if (signatures == NULL)
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "signature: ed25519: commit have no signatures of my type");
+      goto err;
+    }
+
+  if (!g_variant_is_of_type (signatures, (GVariantType *) OSTREE_SIGN_METADATA_ED25519_TYPE))
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "signature: ed25519: wrong type passed for verification");
+      goto err;
+    }
+
+  if ((sign->initialized != TRUE) || (sign->public_key == NULL))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                          "Not able to verify: libsodium library isn't initialized properly");
+      goto err;
+    }
+
+#ifdef HAVE_LIBSODIUM
+  g_debug ("verify: data hash = 0x%x", g_bytes_hash(data));
+
+  for (gsize i = 0; i < g_variant_n_children(signatures); i++)
+    {
+      g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i);
+      g_autoptr (GBytes) signature = g_variant_get_data_as_bytes(child);
+
+      g_autofree char * hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1);
+
+      g_debug("Read signature %d: %s", (gint)i, g_variant_print(child, TRUE));
+
+      if (crypto_sign_verify_detached ((guchar *) g_variant_get_data (child),
+                                       g_bytes_get_data (data, NULL),
+                                       g_bytes_get_size (data),
+                                       sign->public_key) != 0)
+        {
+          /* Incorrect signature! */
+          g_debug("Signature couldn't be verified with key '%s'", 
+                  sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, sign->public_key, crypto_sign_PUBLICKEYBYTES));
+        }
+      else
+        {
+          ret = TRUE;
+          g_debug ("Signature verified successfully with key '%s'",
+                   sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, sign->public_key, crypto_sign_PUBLICKEYBYTES));
+        }
+    }
+
+  if (ret != TRUE)
+    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                         "Not able to verify: no valid signatures found");
+#endif /* HAVE_LIBSODIUM */
+
+  return ret;
+err:
+  return FALSE;
+}
+
+gboolean
+ostree_sign_ed25519_keypair_generate (OstreeSign *self,
+                                      GVariant **out_secret_key,
+                                      GVariant **out_public_key,
+                                      GError **error)
+ {
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+  OstreeSignEd25519 *sign = ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self));
+
+  if (sign->initialized != TRUE)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                          "Not able to sign -- libsodium library isn't initialized properly");
+      goto err;
+    }
+
+#ifdef HAVE_LIBSODIUM
+  unsigned char pk[crypto_sign_PUBLICKEYBYTES];
+  unsigned char sk[crypto_sign_SECRETKEYBYTES];
+
+  if (crypto_sign_keypair(pk, sk))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                          "Not able to generate keypair");
+      goto err;
+    }
+
+  *out_secret_key = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, sk, crypto_sign_SECRETKEYBYTES, sizeof(guchar));
+  *out_public_key = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, pk, crypto_sign_PUBLICKEYBYTES, sizeof(guchar));
+
+  return TRUE;
+#endif /* HAVE_LIBSODIUM */
+
+err:
+  return FALSE;
+}
+
+gboolean ostree_sign_ed25519_set_sk (OstreeSign *self,
+                                     GVariant *secret_key,
+                                     GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+#ifdef HAVE_LIBSODIUM
+  OstreeSignEd25519 *sign = ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self));
+  g_autofree char * hex = NULL;
+
+  g_free (sign->secret_key);
+
+  gsize n_elements = 0;
+  sign->secret_key = (guchar *) g_variant_get_fixed_array (secret_key, &n_elements, sizeof(guchar));
+
+  if (n_elements != crypto_sign_SECRETKEYBYTES)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Incorrect ed25519 secret key");
+      goto err;
+    }
+
+  hex = g_malloc0 (crypto_sign_SECRETKEYBYTES*2 + 1);
+  g_debug ("Set ed25519 secret key = %s", sodium_bin2hex (hex, crypto_sign_SECRETKEYBYTES*2+1, sign->secret_key, n_elements));
+
+  return TRUE;
+
+err:
+#endif /* HAVE_LIBSODIUM */
+  return FALSE;
+}
+
+gboolean ostree_sign_ed25519_set_pk (OstreeSign *self,
+                                     GVariant *public_key,
+                                     GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+#ifdef HAVE_LIBSODIUM
+  OstreeSignEd25519 *sign = ostree_sign_ed25519_get_instance_private(OSTREE_SIGN_ED25519(self));
+  g_autofree char * hex = NULL;
+
+  gsize n_elements = 0;
+  g_free (sign->public_key);
+  sign->public_key = (guchar *) g_variant_get_fixed_array (public_key, &n_elements, sizeof(guchar));
+
+  hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1);
+  g_debug ("Read ed25519 public key = %s", sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, sign->public_key, n_elements));
+
+  if (n_elements != crypto_sign_PUBLICKEYBYTES)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Incorrect ed25519 public key");
+      goto err;
+    }
+
+  g_debug ("Set ed25519 public key = %s", sodium_bin2hex (hex, crypto_sign_PUBLICKEYBYTES*2+1, sign->public_key, n_elements));
+
+  return TRUE;
+
+err:
+#endif /* HAVE_LIBSODIUM */
+  return FALSE;
+}
diff --git a/src/libostree/ostree-sign-ed25519.h b/src/libostree/ostree-sign-ed25519.h
new file mode 100644 (file)
index 0000000..d4a6b56
--- /dev/null
@@ -0,0 +1,75 @@
+/* vim:set et sw=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e2s: */
+
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *  - Denis Pynkin (d4s) <denis.pynkin@collabora.com>
+ */
+
+#pragma once
+
+#include "ostree-sign.h"
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_SIGN_ED25519 (ostree_sign_ed25519_get_type ())
+
+_OSTREE_PUBLIC
+G_DECLARE_FINAL_TYPE (OstreeSignEd25519,
+                      ostree_sign_ed25519,
+                      OSTREE,
+                      SIGN_ED25519,
+                      GObject)
+
+
+gboolean ostree_sign_ed25519_data (OstreeSign *self,
+                                 GBytes *data,
+                                 GBytes **signature,
+                                 GCancellable *cancellable,
+                                 GError **error);
+
+gchar * ostree_sign_ed25519_get_name (OstreeSign *self);
+gchar * ostree_sign_ed25519_metadata_key (OstreeSign *self);
+gchar * ostree_sign_ed25519_metadata_format (OstreeSign *self);
+
+gboolean ostree_sign_ed25519_metadata_verify (OstreeSign *self,
+                                            GBytes     *data,
+                                            GVariant   *signatures,
+                                            GError     **error);
+
+gboolean ostree_sign_ed25519_set_sk (OstreeSign *self,
+                                     GVariant *secret_key,
+                                     GError **error);
+
+gboolean ostree_sign_ed25519_set_pk (OstreeSign *self,
+                                     GVariant *public_key,
+                                     GError **error);
+
+void ostree_sign_ed25519_finalize (GObject *gobject);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_ed25519_keypair_generate (OstreeSign *self,
+                                               GVariant **out_secret_key,
+                                               GVariant **out_public_key,
+                                               GError **error);
+
+G_END_DECLS
+
diff --git a/src/libostree/ostree-sign.c b/src/libostree/ostree-sign.c
new file mode 100644 (file)
index 0000000..96455f8
--- /dev/null
@@ -0,0 +1,347 @@
+/* vim:set et sw=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e2s: */
+
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include "libglnx.h"
+#include "otutil.h"
+
+#include "ostree-autocleanups.h"
+#include "ostree-core.h"
+#include "ostree-sign.h"
+#include "ostree-sign-dummy.h"
+#ifdef HAVE_LIBSODIUM
+#include "ostree-sign-ed25519.h"
+#endif
+
+#define G_LOG_DOMAIN "OSTreeSign"
+
+G_DEFINE_INTERFACE (OstreeSign, ostree_sign, G_TYPE_OBJECT)
+
+static void
+ostree_sign_default_init (OstreeSignInterface *iface)
+{
+  g_debug ("OstreeSign initialization");
+}
+
+gchar * ostree_sign_metadata_key (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_key != NULL, NULL);
+  return OSTREE_SIGN_GET_IFACE (self)->metadata_key (self);
+}
+
+gchar * ostree_sign_metadata_format (OstreeSign *self)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_format != NULL, NULL);
+  return OSTREE_SIGN_GET_IFACE (self)->metadata_format (self);
+}
+
+gboolean ostree_sign_set_sk (OstreeSign *self,
+                             GVariant *secret_key,
+                             GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  if (OSTREE_SIGN_GET_IFACE (self)->set_sk == NULL)
+    return TRUE;
+
+  return OSTREE_SIGN_GET_IFACE (self)->set_sk (self, secret_key, error);
+}
+
+gboolean ostree_sign_set_pk (OstreeSign *self,
+                             GVariant *public_key,
+                             GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  if (OSTREE_SIGN_GET_IFACE (self)->set_pk == NULL)
+    return TRUE;
+
+  return OSTREE_SIGN_GET_IFACE (self)->set_pk (self, public_key, error);
+}
+
+/* Load private keys for verification from anywhere.
+ * No need to have the same function for secret keys -- the signing SW must do it in it's own way
+ * */
+gboolean
+ostree_sign_load_pk (OstreeSign *self,
+                     gchar *remote_name,
+                     GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->load_pk != NULL, FALSE);
+
+  if (remote_name == NULL)
+    remote_name = OSTREE_SIGN_ALL_REMOTES;
+
+  return OSTREE_SIGN_GET_IFACE (self)->load_pk (self, remote_name, error);
+}
+
+gboolean ostree_sign_data (OstreeSign *self,
+                           GBytes *data,
+                           GBytes **signature,
+                           GCancellable *cancellable,
+                           GError **error)
+{
+
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+  g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->data != NULL, FALSE);
+
+  return OSTREE_SIGN_GET_IFACE (self)->data (self, data, signature, cancellable, error);
+}
+
+/*
+ * Adopted version of _ostree_detached_metadata_append_gpg_sig ()
+ */
+GVariant *
+ostree_sign_detached_metadata_append (OstreeSign *self,
+                                      GVariant   *existing_metadata,
+                                      GBytes     *signature_bytes)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (signature_bytes != NULL, FALSE);
+
+  GVariantDict metadata_dict;
+  g_autoptr(GVariant) signature_data = NULL;
+  g_autoptr(GVariantBuilder) signature_builder = NULL;
+
+  g_variant_dict_init (&metadata_dict, existing_metadata);
+
+  g_autofree gchar *signature_key = ostree_sign_metadata_key(self);
+  g_autofree GVariantType *signature_format = (GVariantType *) ostree_sign_metadata_format(self);
+
+  signature_data = g_variant_dict_lookup_value (&metadata_dict,
+                                                signature_key,
+                                                (GVariantType*)signature_format);
+
+  /* signature_data may be NULL */
+  signature_builder = ot_util_variant_builder_from_variant (signature_data, signature_format);
+
+  g_variant_builder_add (signature_builder, "@ay", ot_gvariant_new_ay_bytes (signature_bytes));
+
+  g_variant_dict_insert_value (&metadata_dict,
+                               signature_key,
+                               g_variant_builder_end (signature_builder));
+
+  return  g_variant_dict_end (&metadata_dict);
+}
+
+
+gboolean
+ostree_sign_metadata_verify (OstreeSign *self,
+                             GBytes     *data,
+                             GVariant   *signatures,
+                             GError     **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+  g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_verify != NULL, FALSE);
+
+  return OSTREE_SIGN_GET_IFACE (self)->metadata_verify(self, data, signatures, error);
+}
+
+gboolean
+ostree_sign_commit_verify (OstreeSign     *self,
+                           OstreeRepo     *repo,
+                           const gchar    *commit_checksum,
+                           GCancellable   *cancellable,
+                           GError         **error)
+
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+
+  g_autoptr(GVariant) commit_variant = NULL;
+  /* Load the commit */
+  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
+                                 commit_checksum, &commit_variant,
+                                 error))
+    return glnx_prefix_error (error, "Failed to read commit");
+
+  /* Load the metadata */
+  g_autoptr(GVariant) metadata = NULL;
+  if (!ostree_repo_read_commit_detached_metadata (repo,
+                                                  commit_checksum,
+                                                  &metadata,
+                                                  cancellable,
+                                                  error))
+    return glnx_prefix_error (error, "Failed to read detached metadata");
+
+  g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit_variant);
+
+  /* XXX This is a hackish way to indicate to use ALL remote-specific
+   *     keyrings in the signature verification.  We want this when
+   *     verifying a signed commit that's already been pulled. */
+/*
+  if (remote_name == NULL)
+    remote_name = OSTREE_ALL_REMOTES;
+*/
+
+  g_autoptr(GVariant) signatures = NULL;
+
+  g_autofree gchar *signature_key = ostree_sign_metadata_key(self);
+  g_autofree GVariantType *signature_format = (GVariantType *) ostree_sign_metadata_format(self);
+
+  if (metadata)
+    signatures = g_variant_lookup_value (metadata,
+                                         signature_key,
+                                         signature_format);
+
+
+  return ostree_sign_metadata_verify (self,
+                                      signed_data,
+                                      signatures,
+                                      error);
+}
+
+const gchar * ostree_sign_get_name (OstreeSign *self)
+{
+    g_debug ("%s enter", __FUNCTION__);
+    g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+    g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->get_name != NULL, FALSE);
+
+    return OSTREE_SIGN_GET_IFACE (self)->get_name (self);
+}
+
+OstreeSign * ostree_sign_get_by_name (const gchar *name, GError **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  GType types [] = {
+#if defined(HAVE_LIBSODIUM)
+          OSTREE_TYPE_SIGN_ED25519,
+#endif
+          OSTREE_TYPE_SIGN_DUMMY
+  };
+  OstreeSign *ret = NULL;
+
+  for (gint i=0; i < G_N_ELEMENTS(types); i++)
+  {
+    g_autoptr (OstreeSign) sign = g_object_new (types[i], NULL);
+    g_autofree gchar *sign_name = OSTREE_SIGN_GET_IFACE (sign)->get_name(sign);
+
+    g_debug ("Found '%s' signing module", sign_name);
+
+    if (g_strcmp0 (name, sign_name) == 0)
+    {
+      ret = g_steal_pointer (&sign);
+      break;
+    }
+  }
+
+  if (ret == NULL)
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "Requested signature type is not implemented");
+
+  return ret;
+}
+
+
+/**
+ * ostree_sign_commit:
+ * @self: Self
+ * @commit_checksum: SHA256 of given commit to sign
+ * @cancellable: A #GCancellable
+ * @error: a #GError
+ *
+ * Add a GPG signature to a commit.
+ */
+gboolean
+ostree_sign_commit (OstreeSign     *self,
+                    OstreeRepo     *repo,
+                    const gchar    *commit_checksum,
+                    GCancellable   *cancellable,
+                    GError         **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  g_autoptr(GBytes) commit_data = NULL;
+  g_autoptr(GBytes) signature = NULL;
+  g_autoptr(GVariant) commit_variant = NULL;
+  g_autoptr(GVariant) old_metadata = NULL;
+  g_autoptr(GVariant) new_metadata = NULL;
+
+  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
+                                 commit_checksum, &commit_variant, error))
+    return glnx_prefix_error (error, "Failed to read commit");
+
+  if (!ostree_repo_read_commit_detached_metadata (repo,
+                                                  commit_checksum,
+                                                  &old_metadata,
+                                                  cancellable,
+                                                  error))
+    return glnx_prefix_error (error, "Failed to read detached metadata");
+
+  // TODO: d4s: check if already signed?
+
+  commit_data = g_variant_get_data_as_bytes (commit_variant);
+
+  if (!ostree_sign_data (self, commit_data, &signature,
+                         cancellable, error))
+    return glnx_prefix_error (error, "Not able to sign the cobject");
+
+  new_metadata =
+    ostree_sign_detached_metadata_append (self, old_metadata, signature);
+
+  if (!ostree_repo_write_commit_detached_metadata (repo,
+                                                   commit_checksum,
+                                                   new_metadata,
+                                                   cancellable,
+                                                   error))
+    return FALSE;
+
+  return TRUE;
+}
+
+GStrv ostree_sign_list_names(void)
+{
+  g_debug ("%s enter", __FUNCTION__);
+
+  GType types [] = {
+#if defined(HAVE_LIBSODIUM)
+          OSTREE_TYPE_SIGN_ED25519,
+#endif
+          OSTREE_TYPE_SIGN_DUMMY
+  };
+  GStrv names = g_new0 (char *, G_N_ELEMENTS(types)+1); 
+  gint i = 0;
+
+  for (i=0; i < G_N_ELEMENTS(types); i++)
+  {
+    g_autoptr (OstreeSign) sign = g_object_new (types[i], NULL);
+    names[i] = OSTREE_SIGN_GET_IFACE (sign)->get_name(sign);
+    g_debug ("Found '%s' signing module", names[i]);
+  }
+
+  return names;
+}
diff --git a/src/libostree/ostree-sign.h b/src/libostree/ostree-sign.h
new file mode 100644 (file)
index 0000000..f06206a
--- /dev/null
@@ -0,0 +1,156 @@
+/* vim:set et sw=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e2s: */
+
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *  - Denis Pynkin (d4s) <denis.pynkin@collabora.com>
+ */
+
+#pragma once
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "ostree-ref.h"
+#include "ostree-remote.h"
+#include "ostree-types.h"
+
+/* Special remote */
+#define OSTREE_SIGN_ALL_REMOTES "__OSTREE_ALL_REMOTES__"
+
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_SIGN (ostree_sign_get_type ())
+
+_OSTREE_PUBLIC
+G_DECLARE_INTERFACE (OstreeSign, ostree_sign, OSTREE, SIGN, GObject)
+
+struct _OstreeSignInterface
+{
+  GTypeInterface g_iface;
+  gchar *(* get_name) (OstreeSign *self);
+  gboolean (* data)   (OstreeSign *self,
+                       GBytes *data,
+                       GBytes **signature,
+                       GCancellable *cancellable,
+                       GError **error);
+  gchar *(* metadata_key) (OstreeSign *self);
+  gchar *(* metadata_format) (OstreeSign *self);
+  gboolean (* metadata_verify) (OstreeSign *self,
+                                GBytes *data,
+                                GVariant   *metadata,
+                                GError **error);
+
+  gboolean (* set_sk) (OstreeSign *self,
+                       GVariant *secret_key,
+                       GError **error);
+
+  gboolean (* set_pk) (OstreeSign *self,
+                       GVariant *public_key,
+                       GError **error);
+
+  gboolean (* load_pk) (OstreeSign *self,
+                        gchar *remote_name,
+                        GError **error);
+
+};
+
+_OSTREE_PUBLIC
+const gchar * ostree_sign_get_name (OstreeSign *self);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_data (OstreeSign *self,
+                             GBytes *data,
+                             GBytes **signature,
+                             GCancellable *cancellable,
+                             GError **error);
+
+
+_OSTREE_PUBLIC
+gchar * ostree_sign_metadata_key (OstreeSign *self);
+
+_OSTREE_PUBLIC
+gchar * ostree_sign_metadata_format (OstreeSign *self);
+
+_OSTREE_PUBLIC
+GVariant * ostree_sign_detached_metadata_append (OstreeSign *self,
+                                                 GVariant   *existing_metadata,
+                                                 GBytes     *signature_bytes);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_commit (OstreeSign     *self,
+                             OstreeRepo     *repo,
+                             const gchar    *commit_checksum,
+                             GCancellable   *cancellable,
+                             GError         **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_metadata_verify (OstreeSign *self,
+                                      GBytes     *data,
+                                      GVariant   *signatures,
+                                      GError     **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_commit_verify (OstreeSign *self,
+                                    OstreeRepo     *repo,
+                                    const gchar    *commit_checksum,
+                                    GCancellable   *cancellable,
+                                    GError         **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_set_sk (OstreeSign *self,
+                             GVariant *secret_key,
+                             GError **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_set_pk (OstreeSign *self,
+                             GVariant *public_key,
+                             GError **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_sign_load_pk (OstreeSign *self,
+                              gchar *remote_name,
+                              GError **error);
+
+
+/**
+ * ostree_sign_list_names:
+ *
+ * Return the array with all available sign modules names.
+ *
+ * Returns: (transfer full): an array of strings, free when you used it
+ */
+_OSTREE_PUBLIC
+GStrv ostree_sign_list_names(void);
+
+/**
+ * ostree_sign_get_by_name:
+ *
+ * Tries to find and return proper signing engine by it's name.
+ *
+ * Returns: (transfer full): a constant, free when you used it
+ */
+_OSTREE_PUBLIC
+OstreeSign * ostree_sign_get_by_name (const gchar *name, GError **error);
+
+G_END_DECLS
+